#include <sockLib.h>
#include <inetLib.h>
#include <ioLib.h>
#include <stdio.h>
#include <logLib.h>
#include <string.h>
#include "SimUdpFunc.h"

static int g_socketId = 0;

static void Message2NetAddr(struct sockaddr_in * addr, const UDP_MESSAGE_T *message)
{
	bzero((char*)addr, sizeof(struct sockaddr_in));
	addr->sin_family = AF_INET;
	addr->sin_port = htons(message->port);
	addr->sin_addr.s_addr = message->ip;
}

void ReleaseUdp(void)
{
	if(g_socketId > 0)
	{
		close(g_socketId);
		g_socketId = 0;
	}	
}

void InitializeUdp(void)
{
	BOOL reuse = 1;
	
	if((g_socketId = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
	{
		printf("!!!udp socket failed errno %d\n",errno);
	}
	else
	{
		printf("udp init success!\n");
	}
	
	setsockopt(g_socketId, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse));	
}

void CloseUdpFuncImplement(UDP_MESSAGE_T *message)
{
	if (message != NULL && message->socket > 0)
	{
		close(message->socket);
		message->socket = 0;
	}	
}

void OpenUdpFuncImplement(UDP_MESSAGE_T *message)
{
	int on = 1;
	uint32_t addrSize;
	struct sockaddr_in addr;
	
	if (message != NULL)
	{
		if (message->ip == 0)
		{
			message->socket = socket(AF_INET, SOCK_DGRAM, 0);
			if (message->socket < 0)
			{
				printf("***creat sock failed,in port:%d errno:%d\n",message->port, errno);
				return;
			}

			Message2NetAddr(&addr, message);
			addrSize = sizeof(struct sockaddr_in);

			ioctl(message->socket, FIONBIO, &on);
			message->status = bind(message->socket, (struct sockaddr *)&addr,addrSize);
			if (message->status < 0)
			{
				printf("!!!!bind failed:%d,errno:%d\n",message->port,errno);
				close(message->socket);
				message->socket = 0;
			}
		}
	}	
}

void WriteUdpFuncImplement(UDP_MESSAGE_T *message)
{
	int sockAddrSize;
	struct sockaddr_in targetAddr;

	if (g_socketId > 0)
	{
		sockAddrSize = sizeof(struct sockaddr_in);
		Message2NetAddr(&targetAddr, message);

		sendto(g_socketId, (void *) message->buff, message->buffLength, 0,(SOCKADDR*)&targetAddr, sockAddrSize);
	}
}

void ReadUdpFuncImplement(UDP_MESSAGE_T *message)
{
	int sockAddrSize;
	struct sockaddr_in targetAddr;
	
	if (message != NULL && message->socket > 0) 
	{
		sockAddrSize = sizeof(struct sockaddr_in);
		Message2NetAddr(&targetAddr, message);

		message->status = recvfrom(message->socket, (char*)message->buff,message->buffLength, MSG_DONTWAIT, (SOCKADDR*)&targetAddr, &sockAddrSize);
	}	
}
